package com.mhc.haval.security.filter;

import com.alibaba.fastjson.JSONObject;
import com.mhc.haval.security.constant.Authorities;
import com.mhc.haval.security.constant.Charset;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Scanner;


/**
 * 自定义登录认证过滤器
 *
 * @author Churry
 * @create 2017-08-21 11:43
 **/
@Slf4j
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    /**
     * 如果登录请求是json格式的，按照自定义的格式获取数据
     * @param request
     * @param response
     * @return
     * @throws AuthenticationException
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        //attempt Authentication when Content-Type is json
        //POST login only
        boolean jsonCondition = (request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE) || request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE));
        if (request.getMethod().equals(RequestMethod.POST.name()) && jsonCondition) {
            UsernamePasswordAuthenticationToken authRequest = null;
            try {
                StringBuffer receiveMessage = new StringBuffer();
                Scanner scanner = new Scanner(request.getInputStream(), Charset.GBK);
                while (scanner.hasNext()) {
                    receiveMessage.append(scanner.next());
                }
                scanner.close();
                JSONObject loginParams = JSONObject.parseObject(receiveMessage.toString());
                authRequest = new UsernamePasswordAuthenticationToken(loginParams.get(Authorities.USERNAME_PARAMETER), loginParams.get(Authorities.PASSWORD_PARAMETER));
                this.setDetails(request, authRequest);
                return this.getAuthenticationManager().authenticate(authRequest);
            } catch (IOException e) {
                log.error("IOException", e);
                authRequest = new UsernamePasswordAuthenticationToken("", "");
                this.setDetails(request, authRequest);
                return this.getAuthenticationManager().authenticate(authRequest);
            }
        }
        //transmit it to UsernamePasswordAuthenticationFilter
        else {
            return super.attemptAuthentication(request, response);
        }
    }
}
